#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QMessageBox>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    socket = new QLocalSocket(this);

    connect(socket, SIGNAL(readyRead()), this, SLOT(readFortune()));
    connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)),
            this, SLOT(displayError(QLocalSocket::LocalSocketError)));
}

// 连接到服务器，abort()断开当前连接，重置socket。
void Widget::requestNewFortune()
{
    ui->getFortuneButton->setEnabled(false);
    blockSize = 0;
    socket->abort();
    socket->connectToServer(ui->hostLineEdit->text());
}

// 读取服务器端发送的数据
void Widget::readFortune()
{
    // 读取接收到的数据
    QDataStream in(socket);
    in.setVersion(QDataStream::Qt_4_0);

    if (blockSize == 0) {
        if (socket->bytesAvailable() < (int)sizeof(quint16))
            return;
        in >> blockSize;
    }

    if (in.atEnd())
        return;

    QString nextFortune;
    in >> nextFortune;

    // 如果当前的数据和收到的数据相同，则重新请求一次，因为是随机的字符串，所以肯定不会每次都相同。
    if (nextFortune == currentFortune) {
        QTimer::singleShot(0, this, SLOT(requestNewFortune()));
        return;
    }

    currentFortune = nextFortune;
    ui->statusLabel->setText(currentFortune);
    ui->getFortuneButton->setEnabled(true);
}

// 发生错误时，进行错误处理
void Widget::displayError(QLocalSocket::LocalSocketError socketError)
{
    switch (socketError) {
    case QLocalSocket::ServerNotFoundError:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The host was not found. Please check the "
                                    "host name and port settings."));
        break;
    case QLocalSocket::ConnectionRefusedError:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The connection was refused by the peer. "
                                    "Make sure the fortune server is running, "
                                    "and check that the host name and port "
                                    "settings are correct."));
        break;
    case QLocalSocket::PeerClosedError:
        break;
    default:
        QMessageBox::information(this, tr("Fortune Client"),
                                 tr("The following error occurred: %1.")
                                 .arg(socket->errorString()));
    }

    ui->getFortuneButton->setEnabled(true);
}

void Widget::on_getFortuneButton_clicked()
{
    requestNewFortune();
}

Widget::~Widget()
{
    delete ui;
}
